g_autoptr(GBytes) bytes = NULL;
glnx_fd_close int fd = -1;
- bytes = ot_lgetxattrat (self->objects_dir_fd, loose_path_buf,
- "user.ostreemeta", error);
+ /* In bare-user, symlinks are stored as regular files, so we just
+ * always do an open, then query the user.ostreemeta xattr for
+ * more information.
+ */
+ fd = openat (self->objects_dir_fd, loose_path_buf, O_RDONLY | O_CLOEXEC);
+ if (fd < 0)
+ {
+ glnx_set_error_from_errno (error);
+ goto out;
+ }
+
+ bytes = glnx_fgetxattr_bytes (fd, "user.ostreemeta", error);
if (bytes == NULL)
goto out;
mode = g_file_info_get_attribute_uint32 (ret_file_info, "unix::mode");
- /* Optimize this so that we only open the file if we
- * need to; symlinks contain their content, and we only
- * open regular files if the caller has requested an
- * input stream.
- */
- if (S_ISLNK (mode) || out_input)
- {
- fd = openat (self->objects_dir_fd, loose_path_buf, O_RDONLY | O_CLOEXEC);
- if (fd < 0)
- {
- glnx_set_error_from_errno (error);
- goto out;
- }
- }
-
if (S_ISREG (mode) && out_input)
{
g_assert (fd != -1);
return TRUE;
}
-GBytes *
-ot_lgetxattrat (int dfd,
- const char *path,
- const char *attribute,
- GError **error)
-{
- /* A workaround for the lack of lgetxattrat(), thanks to Florian Weimer:
- * https://mail.gnome.org/archives/ostree-list/2014-February/msg00017.html
- */
- g_autofree char *full_path = g_strdup_printf ("/proc/self/fd/%d/%s", dfd, path);
- GBytes *bytes = NULL;
- ssize_t bytes_read, real_size;
- char *buf;
-
- do
- bytes_read = lgetxattr (full_path, attribute, NULL, 0);
- while (G_UNLIKELY (bytes_read < 0 && errno == EINTR));
- if (G_UNLIKELY (bytes_read < 0))
- {
- glnx_set_error_from_errno (error);
- goto out;
- }
-
- buf = g_malloc (bytes_read);
- do
- real_size = lgetxattr (full_path, attribute, buf, bytes_read);
- while (G_UNLIKELY (real_size < 0 && errno == EINTR));
- if (G_UNLIKELY (real_size < 0))
- {
- glnx_set_error_from_errno (error);
- g_free (buf);
- goto out;
- }
-
- bytes = g_bytes_new_take (buf, real_size);
- out:
- return bytes;
-}
-
-gboolean
-ot_lsetxattrat (int dfd,
- const char *path,
- const char *attribute,
- const void *value,
- gsize value_size,
- int flags,
- GError **error)
-{
- /* A workaround for the lack of lsetxattrat(), thanks to Florian Weimer:
- * https://mail.gnome.org/archives/ostree-list/2014-February/msg00017.html
- */
- g_autofree char *full_path = g_strdup_printf ("/proc/self/fd/%d/%s", dfd, path);
- int res;
-
- do
- res = lsetxattr (full_path, "user.ostreemeta", value, value_size, flags);
- while (G_UNLIKELY (res == -1 && errno == EINTR));
- if (G_UNLIKELY (res == -1))
- {
- glnx_set_error_from_errno (error);
- return FALSE;
- }
-
- return TRUE;
-}
-
gboolean
ot_readlinkat_gfile_info (int dfd,
const char *path,